
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JVM指令集与栈操作 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>JVM指令集与栈操作 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">为什么说JVM字节码指令集是实现Java“编写一次，到处运行”特性的核心？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为字节码指令是与平台无关的。Java编译器将源代码编译成字节码后，生成的`.class`文件不依赖于特定的操作系统或硬件架构。JVM通过解析并执行这些指令，或者通过即时编译器(JIT)将它们转换为特定平台的机器代码，从而使Java程序能在不同平台上运行而无需重新编译。</div>
          </div>
          <div class="card-source">来源: JVM指令集概述 -> 1. 字节码指令与平台无关性</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">结构</div>
          <div class="card-question">当一个Java方法被调用时，JVM会为其在栈中创建怎样的执行单元？这个单元主要包含哪些组成部分？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">结构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JVM会为该方法创建一个新的栈帧（Stack Frame）。它主要包含：局部变量表（Local Variables Table）、操作数栈（Operand Stack）、动态链接（Dynamic Linking）、方法返回地址（Return Address）以及可能的附加信息。</div>
          </div>
          <div class="card-source">来源: JVM栈的基本结构 -> 1. 栈帧（Stack Frame）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请简述JVM中一个方法调用的完整生命周期，从压栈到弹栈的过程是怎样的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">方法调用时，JVM会为该方法创建一个新的栈帧并将其压入当前线程的栈中（压栈）。方法执行期间，JVM会根据字节码指令操作此栈帧中的局部变量和操作数栈。方法执行完毕后，该栈帧会被销毁并从栈中弹出（弹栈），程序控制权根据返回地址交还给调用者。如果方法有返回值，返回值会被推送到调用者方法的操作数栈中。</div>
          </div>
          <div class="card-source">来源: 栈的操作与方法调用 -> 1. 方法调用的过程 & 3. 方法返回的过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">JVM如何优化高频执行的代码以提升运行效率？请描述其核心技术。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JVM使用即时编译（JIT, Just-In-Time Compilation）技术。JIT编译器会识别并选择性地将高频执行的“热点代码”字节码编译为本地机器代码，并进行缓存。这样，在后续调用时就可以直接执行高效的本地代码，避免了重复解释字节码的开销。</div>
          </div>
          <div class="card-source">来源: 字节码指令的执行流程 -> 4. 即时编译（JIT）与优化</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请解释JVM中操作数栈（Operand Stack）的核心作用及其后进先出（LIFO）的工作方式。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">操作数栈用于存放方法执行过程中产生的中间结果。它是一个后进先出（LIFO）的数据结构。例如，在进行算术运算时，指令会从操作数栈顶部弹出操作数进行计算，然后将计算结果再压入栈顶。方法调用时的参数传递和返回值的接收也通过操作数栈完成。</div>
          </div>
          <div class="card-source">来源: 栈的操作与方法调用 -> 5. 操作数栈的使用</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">JVM中的栈和堆在功能、生命周期和线程关系上有何根本区别？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">功能上，栈主要用于存储局部变量和方法调用信息，而堆用于存储对象实例和数组。生命周期上，栈的生命周期与方法调用绑定，方法结束其栈帧即被销毁；堆的生命周期则由垃圾回收器（GC）管理。线程关系上，栈是线程私有的，而堆是所有线程共享的。</div>
          </div>
          <div class="card-source">来源: JVM栈的基本结构 -> 5. 栈与堆的区别 & 6. 栈与线程的关系</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">结构</div>
          <div class="card-question">一个字节码指令由哪两部分组成？它们各自的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">结构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">字节码指令由操作码（Opcode）和操作数（Operand）组成。操作码指定了要执行的具体操作，例如加载、存储或算术运算。操作数则指明了该操作所需的参数或数据。</div>
          </div>
          <div class="card-source">来源: JVM指令集概述 -> 2. 字节码指令的组成</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">`iload` 和 `istore` 这两个指令是如何与JVM栈（特别是操作数栈和局部变量表）进行互动的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`iload`是加载指令，它将局部变量表中的某个整型变量加载到操作数栈的栈顶。`istore`是存储指令，它将操作数栈顶部的整型数据弹出，并存储到局部变量表指定索引的位置。这两个指令实现了局部变量表和操作数栈之间的数据传递。</div>
          </div>
          <div class="card-source">来源: 常见JVM指令与栈的互动 -> 2. 加载和存储指令</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">什么是栈溢出（StackOverflowError）？通常由什么原因引起，并且可以通过什么JVM参数进行调整？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">栈溢出（StackOverflowError）是指当方法调用栈的深度超过了为线程分配的栈空间大小时发生的错误。这通常是由于过深的递归调用或过长的方法调用链导致的。可以通过调整JVM的 `-Xss` 启动参数来增加每个线程的栈大小。</div>
          </div>
          <div class="card-source">来源: JVM栈的基本结构 -> 4. 栈的大小与栈溢出</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
